package com.caocaog.market.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caocaog.market.entity.*;
import com.caocaog.market.finance.entity.MkBillBase;
import com.caocaog.market.finance.service.MkBillBaseService;
import com.caocaog.market.mapper.OrderBaseMapper;
import com.caocaog.market.merchant.entity.MkMerchantBasic;
import com.caocaog.market.merchant.service.MkMerchantService;
import com.caocaog.market.service.*;
import com.caocaog.market.toccpt.service.ApiForOrderService;
import com.caocaog.market.toccpt.vo.CcptOrderInfo;
import com.caocaog.market.util.DistanceUtil;
import com.caocaog.market.utils.FePrinterUtil;
import com.caocaog.market.utils.PrintUtil;
import com.caocaog.market.utils.XyyPrinterUtil;
import com.caocaog.market.utils.YlyPrinterUtil;
import com.caocaog.market.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.CheckFailedException;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Comparator.comparing;

/**
 * 商品订单信息表
 *
 * @author yuki Guo
 * @date 2022年2月10日15:03:08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderBaseSDXServiceImpl extends ServiceImpl<OrderBaseMapper, OrderBase> implements IOrderBaseSDXService {
    @Autowired
    private IOrderLineService orderLineService;
    @Autowired
    private IOrderDeliveryService orderDeliveryService;
    @Autowired
    private IOrderPayService orderPayService;
    @Autowired
    private IOrderPromoService orderPromoService;
    @Autowired
    private ShopPromoHisService shopPromoHisService;
    @Autowired
    private GoodsHisService goodsHisService;
    @Autowired
    private IGoodsBasicService goodsBasicService;
    @Autowired
    private IShopBasicService shopBasicService;
    @Autowired
    private GoodsSpecService goodsSpecificationsService;
    @Autowired
    private IMemberAddressService memberAddressService;
    @Autowired
    private ShopDeliveryService shopDeliveryService;
    @Autowired
    private ShopKilometerPriceService shopKilometerPriceService;
    @Autowired
    private IShopTakeoutService shopTakeoutService;
    @Autowired
    private MkBillBaseService mkBillBaseService;
    @Autowired
    private IOrderStatusInfoService orderStatusInfoService;
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private MkMerchantService merchantService;
    @Autowired
    private ShopCartService shopCartService;
    @Autowired
    private ShopPrinterService shopPrinterService;
    @Autowired
    private ApiForOrderService apiForOrderService;
    @Autowired
    private GoodsAttrService goodsAttrService;
    /*@Autowired TODO 04-24号没问题后删除
    private IGoodsSortService goodsSortService;*/
    @Autowired
    private ShopPromoService shopPromoService;

    private GoodsCategoriesService goodsCategoriesService;

    @Autowired
    public void setGoodsCategoriesService(GoodsCategoriesService goodsCategoriesService) {
        this.goodsCategoriesService = goodsCategoriesService;
    }


    @Override
    public Result getShopInfo(ShopInfoVo shopInfoVo) {
        ShopBasic shopBasic = shopBasicService.getById(shopInfoVo.getId());
        if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
            return Result.error("操作异常:店铺不存在或者已被冻结");
        }

        ShopInfoVo vo = new ShopInfoVo();
        String shopId = shopBasic.getId();

        if (oConvertUtils.isEmpty(shopInfoVo.getSortId())) {

            ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>()
                    .eq("shop_Id", shopId));
            ShopDelivery shopDelivery = shopDeliveryService.getOne(new QueryWrapper<ShopDelivery>()
                    .eq("shop_id", shopId));
            List<ShopPromo> shopPromoList = shopPromoService.selectShopPromoByShopId(shopId);
//            List<GoodsSort> goodsSortList = goodsSortService.getShopSortList(shopId); TODO 04-24号没问题后删除
            List<GoodsCategories> goodsSortList = this.goodsCategoriesService.getShowGoodsCategoriesByShopId(shopId);

            // TODO 这个应该没用过，待确定，没用就删掉
            List<GoodsVo> goodsVoPushList = goodsBasicService.getShopOfGoodsPushList(shopId, 2);

//            this.getGoodsInfo(goodsVoPushList);
            BeanUtils.copyProperties(shopBasic, vo);
            vo.setGoodsVoPushList(goodsVoPushList);
            vo.setShopDelivery(shopDelivery);
            vo.setShopTakeout(shopTakeout);
            vo.setShopPromoList(shopPromoList);
            vo.setGoodsSortList(goodsSortList);
            vo.setSortId(!goodsSortList.isEmpty() ? goodsSortList.get(0).getId() : "");
        }
        return Result.OK(vo);
    }

    /*private List<GoodsVo> getGoodsInfo(List<GoodsVo> goodsVos) {
        for (GoodsVo vo : goodsVos) {
            vo = goodsBasicService.getGoodsInfo(vo);
        }
        return goodsVos;
    }*/

    @Override
    public Page getShopOfGoodsList(GoodsBasic goodsBasic,Integer pageNo, Integer pageSize) {
        Page<GoodsBasic> page = new Page<GoodsBasic>(pageNo, pageSize);
        QueryWrapper<GoodsBasic> queryWrapper = QueryGenerator.initQueryWrapper(goodsBasic, null);
        queryWrapper.eq("status",1);
        Page<GoodsBasic> goodsBasicPage = goodsBasicService.page(page,queryWrapper);

        for (GoodsBasic basic: goodsBasicPage.getRecords()){
            List<GoodsAttr> attributeList = goodsAttrService.getGoodsAttrByGoodsId(basic.getId());
            List<GoodsSpec> specificationsList = goodsSpecificationsService.getGoodsSpecByGoodsId(basic.getId());

            basic.setGoodsAttributeList(attributeList);
            basic.setGoodsSpecificationsList(specificationsList);

        }
        return goodsBasicPage;
    }
    @Override
    public OrderBase selectOrderInfo(String orderId) {
        OrderBase orderBase = this.baseMapper.selectById(orderId);
        if (null == orderBase) {
            throw new JeecgBootException("订单不存在");
        }
        //order pay
        //order promo
        //order delivery
        //order line
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderId));
        OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", orderId));
        List<OrderPromo> orderPromos = orderPromoService.list(new QueryWrapper<OrderPromo>().eq("order_id", orderId));
        List<ShopPromoHis> orderPromoList = new ArrayList<>();
        if (oConvertUtils.isNotEmpty(orderPromos)) {
            for (OrderPromo promo : orderPromos) {
                ShopPromoHis shopPromo = shopPromoHisService.getById(promo.getPromoId());
                orderPromoList.add(shopPromo);
            }
        }
        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId));
        ShopBasic shopBasic = shopBasicService.getById(orderBase.getShopId());
        if (null != shopBasic) {
            orderBase.setLat(shopBasic.getLat());
            orderBase.setLng(shopBasic.getLng());
            orderBase.setShopLogo(shopBasic.getLogo());
            orderBase.setShopName(shopBasic.getName());
        }
        for (OrderLine orderLine : orderLineList) {
            GoodsHis goodsHis = goodsHisService.getByIdCache(orderLine.getGoodsHisId());
            if (null != goodsHis) {
                orderLine.setPicture(goodsHis.getPicture());
            }
        }
        CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(orderBase);
        if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
            orderBase.setCcptOrderInfo(ccptOrderInfo);
        }
        orderBase.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
        orderBase.setOrderDelivery(orderDelivery);
        orderBase.setOrderLineList(orderLineList);
        orderBase.setOrderPromoList(orderPromoList);
        return orderBase;
    }

    @Override
    public OrderBase selectOrderInfoByOrderNo(String orderNo) {
        OrderBase orderBase = this.baseMapper.selectOne(new QueryWrapper<OrderBase>().eq("order_no", orderNo));
        String orderId = orderBase.getId();
        //order pay
        //order promo
        //order delivery
        //order line
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderId));
        OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", orderId));
        List<OrderPromo> orderPromos = orderPromoService.list(new QueryWrapper<OrderPromo>().eq("order_id", orderId));
        List<ShopPromoHis> orderPromoList = new ArrayList<>();
        if (oConvertUtils.isNotEmpty(orderPromos)) {
            for (OrderPromo promo : orderPromos) {
                ShopPromoHis shopPromo = shopPromoHisService.getById(promo.getPromoId());
                orderPromoList.add(shopPromo);
            }
        }

        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId));
        orderBase.setOrderPay(orderPay);
        orderBase.setOrderDelivery(orderDelivery);
        orderBase.setOrderLineList(orderLineList);
        orderBase.setOrderPromoList(orderPromoList);
        CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(orderBase);
        if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
            orderBase.setCcptOrderInfo(ccptOrderInfo);
        }
        return orderBase;
    }

    @Override
    public IPage<OrderBase> selectOrderListForMember(OrderBase orderBase, Integer pageNo, Integer pageSize) {
        //全部 配送单 自提单 退款
        QueryWrapper<OrderBase> queryWrapper = QueryGenerator.initQueryWrapper(orderBase, null);
        Page<OrderBase> page = new Page<OrderBase>(pageNo, pageSize);
        queryWrapper.eq("member_id", orderBase.getMemberId());
        queryWrapper.eq("is_show", 0);
        boolean search_refund = false;
        if (oConvertUtils.isNotEmpty(orderBase.getStatus())) {
            queryWrapper.eq("status", orderBase.getStatus());
            search_refund = true;
        }
        if (oConvertUtils.isNotEmpty(orderBase.getType())) {
            queryWrapper.eq("type", orderBase.getType());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<OrderBase> orderBaseList = super.baseMapper.selectPage(page, queryWrapper);

        for (OrderBase base : orderBaseList.getRecords()) {
            List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", base.getId()));
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", base.getId()));
            OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", base.getId()));
            ShopBasic shopBasic = shopBasicService.getById(base.getShopId());
            base.setShopLogo(null == shopBasic ? "" : shopBasic.getLogo());
            base.setOrderLineList(orderLineList.size() > 0 ? orderLineList : new ArrayList<>());
            base.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
            base.setOrderDelivery(null == orderDelivery ? new OrderDelivery() : orderDelivery);
            //
            if (search_refund) {
                OrderRefund orderRefund = orderRefundService.getOne(new QueryWrapper<OrderRefund>().eq("order_id", base.getId()));
                base.setOrderRefund(null == orderRefund ? new OrderRefund() : orderRefund);
            }
            if (base.getStatus().equals("2")) {
                CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(base);
                if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
                    base.setCcptOrderInfo(ccptOrderInfo);
                }
            }
        }

        return orderBaseList;
    }

    @Override
    public CcptOrderInfo getCcptOrderInfo(OrderBase orderBase) {
        try {
            //获取跑腿骑士详情
            Result result = apiForOrderService.findCcptOrderStatus(orderBase.getId());
            if (result.isSuccess()) {
                JSONObject jsonObject = new JSONObject(result.getResult());
                CcptOrderInfo ccptOrderInfo = jsonObject.toBean(CcptOrderInfo.class);
                String status = ccptOrderInfo.getCcptOrderStatus();
                /**
                 * 跑腿系统中的订单状态 1：支付成功待接单，2：已接单，3：骑士到店，4：已取货/配送中，5：已送达，6：订单完成，
                 *      下面的这三个状态不用管
                 *      21：用户取消订单，22：代理商取消订单，23：总后台取消订单
                 */
                Date date = new Date();
                if (status.equals("1")) {
                    //支付成功待接单
                } else if (status.equals("2")) {
                    //已接单
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffReceiveTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffReceiveTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(),
                            "骑手已接单", date);
                } else if (status.equals("3")) {
                    //骑手到店
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffReadyTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffReadyTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "骑手已到店", date);
                } else if (status.equals("4")) {
                    //已取货/配送中
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffTakeTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffTakeTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "骑手正在配送中", date);
                } else if (status.equals("5")) {
                    //已送达,订单完成
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffSendTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffSendTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "已送达", date);
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "",
                            "已完成", date);
                }

                return ccptOrderInfo;
            } else {
                log.error("获取骑手信息异常：" + result.getMessage() + " " + orderBase.getOrderNo() + " " + orderBase.getStatus());
                return null;
            }
        } catch (Exception e) {
            throw new JeecgBootException("获取骑手信息异常" + orderBase.getOrderNo() + " " + orderBase.getStatus() + " " + e.getMessage());
        }

    }

    @Override
    public IPage<OrderBase> selectOrderListForMerchant(OrderBase orderBase, Integer pageNo, Integer pageSize) {
        //全部 配送单 自提单 退款
        QueryWrapper<OrderBase> queryWrapper = QueryGenerator.initQueryWrapper(orderBase, null);
        Page<OrderBase> page = new Page<OrderBase>(pageNo, pageSize);
        if (oConvertUtils.isNotEmpty(orderBase.getShopId())) {
            queryWrapper.eq("shop_id", orderBase.getShopId());
        }
        if (oConvertUtils.isNotEmpty(orderBase.getMerchantId())) {
            queryWrapper.eq("merchant_id", orderBase.getMerchantId());
        }

        queryWrapper.notIn("status", 0, -1);
        queryWrapper.eq("is_show", 0);
        boolean search_refund = false;
        if (oConvertUtils.isNotEmpty(orderBase.getStatus())) {
            queryWrapper.eq("status", orderBase.getStatus());
            search_refund = true;
        }
        if (oConvertUtils.isNotEmpty(orderBase.getType())) {
            queryWrapper.eq("type", orderBase.getType());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<OrderBase> orderBaseList = super.baseMapper.selectPage(page, queryWrapper);

        for (OrderBase base : orderBaseList.getRecords()) {
            List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", base.getId()));
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", base.getId()));
            OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", base.getId()));
            ShopBasic shopBasic = shopBasicService.getById(base.getShopId());
            base.setShopLogo(null == shopBasic ? "" : shopBasic.getLogo());
            base.setOrderLineList(orderLineList.size() > 0 ? orderLineList : new ArrayList<>());
            base.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
            base.setOrderDelivery(null == orderDelivery ? new OrderDelivery() : orderDelivery);
            //
            if (search_refund) {
                OrderRefund orderRefund = orderRefundService.getOne(new QueryWrapper<OrderRefund>().eq("order_id", base.getId()));
                base.setOrderRefund(null == orderRefund ? new OrderRefund() : orderRefund);
            }
            if (base.getStatus().equals("2")) {
                CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(base);
                if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
                    base.setCcptOrderInfo(ccptOrderInfo);
                }
            }
        }

        return orderBaseList;
    }

    @Override
    @Transactional
    public Result add(OrderForOneVo vo, Member member) {
        //单商品订单
        //分站 商家 店铺
        //商品行
        //分站
        if (oConvertUtils.isEmpty(vo.getMerchantId())) {
            return Result.error("参数错误");
        }
        if (vo.getOrderLineList().size() < 1) {
            return Result.error("参数错误:请至少选择一个商品下单哦");
        }
        MkMerchantBasic merchant = merchantService.findMerchantById(vo.getMerchantId());
        if (null == merchant) {
            return Result.error("参数错误,暂无此商家");
        }
        OrderBase orderBase = new OrderBase();
        BeanUtils.copyProperties(vo, orderBase);
        orderBase.setSiteId(merchant.getSiteId());
        orderBase.setCreateBy(member.getLoginName());
        orderBase.setCreateTime(new Date());
        /*订单号规则 时间yyyymmddhhmmssSSS加手机号后四位加来源*/
        String phone = member.getMobile();
        Date date = new Date();
        String timestamp = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmssSSS.get());
        String orderNo = "SDX"+timestamp + phone.substring(phone.length() - 5, phone.length()) + vo.getSource();
        orderBase.setOrderNo(orderNo);
        String orderId = IdWorker.getIdStr();
        orderBase.setId(orderId);
        orderBase.setStatus("0");//待付款

        List<GoodsSpec> goodsSpecList = new ArrayList<>();
        List<GoodsBasic> goodsBasicList = new ArrayList<>();
        ShopBasic shopBasic = shopBasicService.getById(vo.getShopId());
        if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
            return Result.error("操作异常:店铺不存在或者已被冻结");
        }
        ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>().eq("shop_id", vo.getShopId()));
        BigDecimal onlineSumPrice = new BigDecimal("0");
        BigDecimal sumPrice = new BigDecimal("0");
        BigDecimal packSumPrice = new BigDecimal("0");
        for (OrderLine line : vo.getOrderLineList()) {
            BigDecimal onlinePrice = new BigDecimal("0");
            GoodsBasic goodsBasic = goodsBasicService.getById(line.getGoodsId());
            if (goodsBasic.getStatus().equals("1") && goodsBasic.getDelFlag() == 0) {
                GoodsHis goodsHis = goodsHisService.getOne(new QueryWrapper<GoodsHis>().eq("goods_id", line.getGoodsId())
                        .orderByDesc("create_time")
                        .last("limit 1"));

                // 更新销量 订单完成后再加
                goodsBasic.setSaleNum(goodsBasic.getSaleNum() + 1);
                goodsBasic.setVisitNum(goodsBasic.getVisitNum() + 1);
                line.setGoodsHisId(goodsHis.getId());
                line.setOrderId(orderId);
                line.setOrderNo(orderNo);
                line.setCreateBy(member.getLoginName());

                //是否选中(有无)规格
                if (oConvertUtils.isNotEmpty(line.getSpecHisId())) {
                    GoodsSpec specifications = goodsSpecificationsService.getGoodsSpec(line.getSpecHisId());
                    //check 合计金额是否正确
                    BigDecimal specOnePrice = new BigDecimal(specifications.getPrice());
                    onlinePrice = new BigDecimal(line.getQuantity())
                            .multiply(specOnePrice);
                    packSumPrice = packSumPrice.add(new BigDecimal(specifications.getPackFee()).multiply(new BigDecimal(line.getQuantity())));
                    // 减库存
                    specifications.setStock(specifications.getStock() - 1);
                    goodsSpecList.add(specifications);
                } else {
                    GoodsSpec goodsSpec = goodsSpecificationsService.getOne(new QueryWrapper<GoodsSpec>()
                            .eq("goods_id", goodsBasic.getId()).last("limit 1"));
                    if (null != goodsSpec) {
                        return Result.error("请选择规格后再下单哟~");
                    }
                    onlinePrice = new BigDecimal(line.getQuantity()).multiply(new BigDecimal(goodsBasic.getPresentPrice()));
                }
                //check 合计金额是否正确
                if (onlinePrice.compareTo(new BigDecimal(line.getTotalPrice())) != 0) {
                    return Result.error("参数错误:合计金额错误~");
                }
                onlineSumPrice = onlineSumPrice.add(onlinePrice);
                goodsBasicList.add(goodsBasic);
            } else {
                //商品已下架
                return Result.error("该商品已经下架了哟");
            }

        }


        OrderPay orderPay = new OrderPay();
        orderPay.setCreateBy(member.getLoginName());
        orderPay.setOrderId(orderId);

        orderPay.setAmount(onlineSumPrice.toString());
        // 打包费
        if (packSumPrice.compareTo(new BigDecimal("0")) == 0) {
            packSumPrice = new BigDecimal(StringUtils.isBlank(shopTakeout.getPack()) ? "0" : shopTakeout.getPack());
        }
        orderPay.setPackAmount(packSumPrice.toString());
        orderPay.setPayStatus(0);//待支付
        // 配送
        OrderDelivery orderDelivery = new OrderDelivery();
        BeanUtils.copyProperties(vo.getOrderDelivery(), orderDelivery);
        orderDelivery.setCreateBy(member.getLoginName());

        if (vo.getType() == 1) {
            orderDelivery.setDeliveryType("1");//电动车
            //外卖订单
            // 配送费
            DistanceVo distanceVo = DistanceVo.builder()
                    .addressId(vo.getAddressId())
                    .shopId(shopBasic.getId())
                    .gpsToLat(Double.parseDouble(shopBasic.getLat()))
                    .gpsToLng(Double.parseDouble(shopBasic.getLng()))
                    .gpsFromLat(Double.parseDouble(orderDelivery.getLat()))
                    .gpsFromLng(Double.parseDouble(orderDelivery.getLng()))
                    .amount(onlineSumPrice.add(packSumPrice).toString())
                    .build();
            distanceVo = this.getDeliveryAmount(distanceVo);
            orderPay.setDeliveryAmount(distanceVo.getDistanceAmount());
            orderDelivery.setDistance(distanceVo.getDistance());
        } else if (vo.getType() == 2 || vo.getType() == 3) {
            //自提单 配送为零
            orderPay.setDeliveryAmount("0");
            orderDelivery.setDistance("0");
            //生成核销码
            String code = this.getVerifyCode(shopBasic.getId());
            orderBase.setVerifyCode(code);
        } else {
            return Result.error("参数错误:值不存在~");
        }

        orderDelivery.setOrderId(orderId);
        // 参与优惠活动
        List<OrderPromo> orderPromoList = new ArrayList<>();
        if (vo.getShopPromoHisList().size() > 0) {
            for (ShopPromoHis his : vo.getShopPromoHisList()) {
                OrderPromo orderPromo = new OrderPromo();
                ShopPromoHis shopPromoHis = shopPromoHisService.getById(his.getId());
                if (null != shopPromoHis) {
                    orderPromo.setOrderId(orderId);
                    orderPromo.setCreateBy(member.getLoginName());
                    orderPromo.setPromoId(his.getId());
                    orderPromoList.add(orderPromo);
                } else {
                    return Result.error("参数错误:未找到该优惠活动~");
                }

            }
            orderPay.setDiscountAmount(vo.getPromoMoney());
        } else {
            //未参与优惠活动
            orderPay.setDiscountAmount("0");
        }
        //实际支付的金额 online商品价格 + 配送费+打包费-优惠金额
        sumPrice = onlineSumPrice.add(new BigDecimal(orderPay.getDeliveryAmount()))
                .add(new BigDecimal(orderPay.getPackAmount()))
                .subtract(new BigDecimal(orderPay.getDiscountAmount()));
        if (sumPrice.compareTo(new BigDecimal("0")) <= 0) {
            //实付金额优惠后金额为零时,最小支付0.01
            sumPrice = new BigDecimal("0.01");
        }
        log.info("实付金额sunPrice:" + sumPrice + " 支付金额:" + vo.getPayMoney());
        if (sumPrice.compareTo(new BigDecimal(vo.getPayMoney())) != 0) {
            return Result.error("操作失败:实付金额错误~");
        }
        orderPay.setPayAmount(sumPrice.toString());
        if (!goodsSpecList.isEmpty()) {
            goodsSpecList.forEach(goodsSpecificationsService::updateGoodsSpec);
        }
        if (!goodsBasicList.isEmpty()) {
            goodsBasicService.updateBatchById(goodsBasicList);
        }
        orderPay.setPayWay(1);//当前默认支付方式为微信小程序
        super.baseMapper.insert(orderBase);
        orderLineService.saveBatch(vo.getOrderLineList());
        orderPayService.save(orderPay);
        orderDeliveryService.addOrderDelivery(orderDelivery);
        if (!orderPromoList.isEmpty()) {
            orderPromoService.saveBatch(orderPromoList);
        }

        //返回订单号 订单金额
//        orderPay.setPayAmount("0.01");
        orderBase.setOrderPay(orderPay);
        //添加状态记录
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "已下单", new Date());
        //清空购物车
        shopCartService.remove(new QueryWrapper<ShopCart>().eq("member_id", vo.getMemberId())
                .eq("shop_id", vo.getShopId()));
        return Result.OK(orderBase);
    }

    @Override
    public void addOrderStatusInfo(String orderId, String orderNo, String createBy, String remark, String statusName, Date date) {
        OrderStatusInfo check = orderStatusInfoService.getOne(new QueryWrapper<OrderStatusInfo>().eq("order_id", orderId)
                .eq("order_status_name", statusName).last(" limit 1 "));
        if (oConvertUtils.isEmpty(check)) {
            //添加状态记录
            OrderStatusInfo orderStatusInfo = OrderStatusInfo.builder().orderId(orderId)
                    .orderNo(orderNo).orderStatusName(statusName).createBy(createBy)
                    .createTime(new Date()).remark(remark).build();
            orderStatusInfoService.save(orderStatusInfo);
            log.info("添加订单状态记录成功：" + orderNo + statusName);
            if ("已完成".equals(statusName)) {
                //更新订单状态
                OrderBase orderBase = super.baseMapper.selectById(orderId);
                if (oConvertUtils.isNotEmpty(orderBase) && !orderBase.getStatus().equals("3")) {
                    orderBase.setStatus("3");
                    super.baseMapper.updateById(orderBase);
                }
            }
        } else {
            log.error("添加订单状态记录失败，该订单状态已存在 ：" + orderNo + statusName);
        }

    }

    @Override
    public DistanceVo getDeliveryAmount(DistanceVo vo) {
        if (oConvertUtils.isEmpty(vo.getGpsFromLat()) || oConvertUtils.isEmpty(vo.getGpsFromLng())) {
            MemberAddress memberAddress = new MemberAddress();
            //无用户的经纬度 则默认返回用户的常用地址信息
            if (oConvertUtils.isNotEmpty(vo.getAddressId())) {
                memberAddress = memberAddressService.getById(vo.getAddressId());
            } else if (oConvertUtils.isNotEmpty(vo.getMemberId())) {
                memberAddress = memberAddressService.getMemberCommonAddress(vo.getMemberId());//返回用户的常用地址top1
            } else {
                throw new JeecgBootException("参数错误");
            }
            if (null == memberAddress) {
                throw new JeecgBootException("请先添加收货地址");
            }
            vo.setGpsFromLat(Double.parseDouble(memberAddress.getLat()));
            vo.setGpsFromLng(Double.parseDouble(memberAddress.getLng()));
            vo.setAddressId(memberAddress.getId());
        }
        Double distance = DistanceUtil.getDistanceMeter(vo.getGpsFromLat(), vo.getGpsFromLng(), vo.getGpsToLat(), vo.getGpsToLng());
        vo.setDistance(String.format("%.2f", distance));
        log.info("配送距离distance:" + distance);
        //获取外卖配送设置
        ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>().eq("shop_id", vo.getShopId()));
        if (null == shopTakeout) {
            log.warn("该店铺id:" + vo.getShopId() + "暂未配置外卖信息");
        } else if (oConvertUtils.isNotEmpty(shopTakeout.getMxDistance()) && distance > Double.parseDouble(shopTakeout.getMxDistance())) {
            throw new JeecgBootException("距离太远啦,暂时不支持配送哦,请换其他店铺试试呢");
        } else if (oConvertUtils.isNotEmpty(shopTakeout.getStartFare()) && new BigDecimal(vo.getAmount()).compareTo(new BigDecimal(shopTakeout.getStartFare())) < 0) {
            throw new JeecgBootException("暂未满足起送条件哦");
        }
        BigDecimal disPrice = new BigDecimal("0").setScale(2, BigDecimal.ROUND_UP);
        //获取符合的配送距离
        if (StringUtils.isNotEmpty(shopTakeout.getFreeDistribution())
                && new BigDecimal(shopTakeout.getFreeDistribution()).compareTo(new BigDecimal("0")) != 0
                && new BigDecimal(vo.getAmount()).compareTo(new BigDecimal(shopTakeout.getFreeDistribution())) >= 0) {
            //免费配送 条件 满金额
            log.info("免费配送条件-满" + shopTakeout.getFreeDistribution() + "金额免配送");
            vo.setDistanceAmount("0");
        } else if (StringUtils.isNotEmpty(shopTakeout.getFreeDistance())
                && Integer.parseInt(shopTakeout.getFreeDistance()) != 0
                && Integer.parseInt(shopTakeout.getFreeDistance()) >= distance) {
            //符合配送的距离
            log.info("符合配送的距离" + shopTakeout.getFreeDistance());
            vo.setDistanceAmount("0");
        } else {
            //不符合免费配送条件
            ShopDelivery shopDelivery = shopDeliveryService.getOne(new QueryWrapper<ShopDelivery>().eq("shop_id", vo.getShopId()));
            if (null != shopDelivery) {
                //起送公里 起送价
//                if (shopDelivery.getStartKilometer().doubleValue() < distance) {
                disPrice = disPrice.add(shopDelivery.getStartPrice());
//                }
                //超出价格 超出公里
                if (distance > shopDelivery.getExceedKilometer().doubleValue()) {
                    BigDecimal exceedPrice = new BigDecimal(distance.toString()).subtract(shopDelivery.getExceedKilometer())
                            .multiply(shopDelivery.getExceedPrice());
                    disPrice = disPrice.add(exceedPrice);
                }
                //配送范围 计算
                if (StringUtils.isNotEmpty(shopDelivery.getIntervalRange())) {
                    String[] kilIds = shopDelivery.getIntervalRange().split(",");
                    List<ShopKilometerPrice> shopKilometerPriceList = shopKilometerPriceService.list(
                            new QueryWrapper<ShopKilometerPrice>().in("id", kilIds)
                                    .orderByAsc("kilometer_str"));
                    Boolean flag = false;
                    BigDecimal defferAmount = new BigDecimal("0");
                    for (ShopKilometerPrice kilometerPrice : shopKilometerPriceList) {
                        BigDecimal differ = new BigDecimal("0");
                        if (distance >= kilometerPrice.getKilometerEnd().doubleValue()) {
                            differ = kilometerPrice.getKilometerEnd().subtract(kilometerPrice.getKilometerStr());//超过此区间内相差
                        } else if (distance < kilometerPrice.getKilometerEnd().doubleValue() && distance > kilometerPrice.getKilometerStr().doubleValue()) {
                            differ = new BigDecimal(distance.toString()).subtract(kilometerPrice.getKilometerStr());//未超过此区间内相差
                            flag = true;
                        } else {
                            break;
                        }
                        defferAmount = defferAmount.add(differ.multiply(kilometerPrice.getPrice()));
                        if (flag) {
                            break;
                        }
                    }
                    disPrice = disPrice.add(defferAmount);
                }

                vo.setDistanceAmount(disPrice.setScale(0, BigDecimal.ROUND_UP).toString());
            } else {
//            if (distance<Double.parseDouble(shopTakeout.getFreeDistance())){
                //符合在免费配送距离内
                vo.setDistanceAmount(disPrice.toString());
            }
        }


        return vo;
    }


    @Override
    public Result goodThingsAroundForSDX(String lat, String lng,Integer pageNo, Integer pageSize) {
        //周边好物
        //周边店铺
        List<ShopVo> shopBasicList = shopBasicService
                .selectShopListAndTakeOutInfoByRecommend(new ShopBasic().setRecommend(1));
        List<ShopVo> shopBasicListNew = new ArrayList<>();
        for (int i=0;i<shopBasicList.size();i++) {
            ShopVo shopVo = shopBasicList.get(i);
            if (oConvertUtils.isNotEmpty(shopVo.getLat()) && oConvertUtils.isNotEmpty(shopVo.getLng())) {
                double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                        Double.parseDouble(shopVo.getLat()), Double.parseDouble(shopVo.getLng()));
                if (distance>Double.parseDouble("100.00")){//周边好物 暂时获取100公里内的
//                    shopBasicList.remove(i);
                    continue;
                }
                shopVo.setDistance(Double.parseDouble(String.format("%.2f", distance)));
                shopBasicListNew.add(shopVo);
            }

        }
        shopBasicListNew.sort(comparing(ShopVo::getDistance));
        List<String> shopIds = shopBasicListNew.stream().map(ShopVo::getId).collect(Collectors.toList());

        Page<GoodsBasic> goodsBasicPage= new Page<>();
        if (oConvertUtils.listIsNotEmpty(shopIds)) {
            List<String> descStr = new ArrayList<>();
            descStr.add("is_hot");
            descStr.add("sale_num");
            Page<GoodsBasic> page = new Page<GoodsBasic>(pageNo, pageSize);
             goodsBasicPage = goodsBasicService.page(page,new QueryWrapper<GoodsBasic>().in("shop_id", shopIds)
                    .eq("is_index", 1)
                    .eq("status", 1)
                    .eq("del_flag", 0)
                    .orderByDesc(descStr));
        }
        return Result.OK(goodsBasicPage);
    }

    @Override
    public Result cancelOrder(String orderId, Member member) {
        // 回滚库存 更新状态
        OrderBase orderBase = super.baseMapper.selectById(orderId);
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderId));
        orderBase.setStatus("-1");//取消
        log.info("------cancelOrder取消订单:" + orderBase.getStatus());
        for (OrderLine line : orderLineList) {
            GoodsHis goodsHis = goodsHisService.getByIdCache(line.getGoodsHisId());
            GoodsBasic goodsBasic = goodsBasicService.getById(goodsHis.getGoodsId());
            if (!line.getSpecHisId().isEmpty()) {
                GoodsSpec goodsSpec = goodsSpecificationsService.getGoodsSpec(line.getSpecHisId());
                goodsSpec.setStock(goodsSpec.getStock() + line.getQuantity());//回滚库存
                goodsSpecificationsService.updateGoodsSpec(goodsSpec);
            }
            goodsBasic.setSaleNum(goodsBasic.getSaleNum() - line.getQuantity());//回滚销量
            goodsBasicService.updateById(goodsBasic);
        }
        super.baseMapper.updateById(orderBase);

        //添加状态记录
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已取消", new Date());
        return Result.OK();
    }

    @Override
    public Result verifyOrder(OrderBase orderBase) {
        // 核销订单
        orderBase.setStatus("3");//已完成
        super.baseMapper.updateById(orderBase);
        //添加状态记录-已核销
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已核销", new Date());

        //添加状态记录-已完成
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已完成", new Date());

        return Result.OK("核销成功");
    }

    @Override
    public Result refundOrder(OrderRefund orderRefund, Member member) {
        // 订单申请退款
        OrderRefund check = orderRefundService.getOne(new QueryWrapper<OrderRefund>()
                .eq("order_id", orderRefund.getOrderId()));
        OrderBase orderBase = super.baseMapper.selectOne(new QueryWrapper<OrderBase>().eq("order_no", orderRefund.getOrderNo()));

        //取消跑腿订单
        if (Integer.parseInt(orderBase.getStatus()) > 1) {//已发货
            //Result result = apiForOrderService.cancelOrderToCcpt(orderRefund.getOrderId());
            Result result = apiForOrderService.cancelOrderToCcpt(orderBase.getId());
            log.info("取消跑腿订单：" + result.isSuccess() + " " + result.getMessage());
            if (!result.isSuccess()) {
                log.error(result.getMessage());
            }
        }
        if (oConvertUtils.isEmpty(check)) {
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderBase.getId()));
            orderRefund.setAudit(0);//待审核
            orderRefund.setPayStatus(0);//待退款
            orderRefund.setOrderStatus(orderBase.getStatus());
            orderRefund.setCreateBy(member.getUserName());
            orderRefund.setCreateTime(new Date());
            orderRefund.setRefundAmount(orderPay.getPayAmount());
            orderRefund.setOrderStatus(orderBase.getStatus());
            orderRefund.setOrderId(orderBase.getId());
            orderRefund.setMerchantId(orderBase.getMerchantId());
            orderRefund.setShopId(orderBase.getShopId());
            /*订单号规则 时间yyyymmddhhmmssSSS加手机号后四位加来源*/
            String phone = member.getMobile();
            Date date = new Date();
            String timestamp = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmssSSS.get());
            String refundNo = "SDXT" + timestamp + phone.substring(phone.length() - 5, phone.length()) + orderBase.getSource();
            orderRefund.setRefundNo(refundNo);
            orderBase.setStatus("-2");//申请售后
            super.baseMapper.updateById(orderBase);
            orderRefundService.save(orderRefund);
            //添加状态记录
            this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), member.getLoginName(), "", "客户申请退款", new Date());
            //更新结算状态  3-待退款
            MkBillBase mkBillBase = mkBillBaseService.findBillIsExist(orderBase.getOrderNo());
            if (oConvertUtils.isNotEmpty(mkBillBase)) {
                mkBillBaseService.updatePayStatusAndInsertHistory(orderBase.getOrderNo(), 3);
            }

        }
        return Result.OK("操作成功");
    }


    @Override
    public List<ShopPromoHis> computeConformPromo(OrderForOneVo orderForOneVo) {
        // 校验
        if (StringUtils.isBlank(orderForOneVo.getShopId()))
            throw new CheckFailedException("店铺id（shopId）不能为空");
        if (StringUtils.isBlank(orderForOneVo.getMemberId()))
            throw new CheckFailedException("会员id（memberId）不能为空");
        if (orderForOneVo.getOrderLineList() == null || orderForOneVo.getOrderLineList().size() == 0)
            throw new CheckFailedException("请传入商品（orderLineList）");
        // 查询店铺下所有的最新促销信息（含历史表id）
        List<ShopPromoHis> shopPromoHiss = this.shopPromoHisService.selectShopPromoHisByShopId(orderForOneVo.getShopId());
        if (shopPromoHiss.size() == 0) return new ArrayList<>();

        // 根据店铺 id 获得店铺外卖信息 并进行校验
        ShopTakeout shopTakeout = this.shopTakeoutService.getOne(
                new LambdaQueryWrapper<ShopTakeout>().eq(ShopTakeout::getShopId, orderForOneVo.getShopId()));
        if (shopTakeout == null)
            throw new JeecgBootException("未找到相应店铺外卖信息, shopId-> " + orderForOneVo.getShopId());

        // 把参数转换为 map<specId, OrderLine>
        Map<String, OrderLine> specIdMap = orderForOneVo.getOrderLineList().stream()
                .collect(Collectors.toMap(OrderLine::getSpecHisId, orderLine -> orderLine));

        // 根据map中所有的规格id查询规格信息
        Map<String, BigDecimal> specPrices = this.goodsSpecificationsService.list(
                new LambdaQueryWrapper<GoodsSpec>().in(GoodsSpec::getId, specIdMap.keySet()))
                .stream().collect(Collectors.toMap(GoodsSpec::getId, goodsSpecifications -> {
                    Integer quantity = specIdMap.get(goodsSpecifications.getId()).getQuantity(); // 获取数量
                    if (quantity == 1) // 如果数量为 1，直接返回规格售价
                        return new BigDecimal(goodsSpecifications.getPrice());
                    else // 规格售价 * 数量
                        return new BigDecimal(goodsSpecifications.getPrice()).multiply(new BigDecimal(quantity));
                }));

        if (specIdMap.size() != specPrices.size())
            throw new JeecgBootException("请传入正确的规格id, 传入的规格id-> " + specIdMap.keySet() + "; 数据库中查出的规格id.size-> " + specPrices.size());

        // 计算出总花费                               // 规格售价 * 数量（使用reduce聚合函数,实现累加器）
        BigDecimal totalCost = BigDecimal.ZERO.add(specPrices.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add));

        // 按照促销类型进行分类
        Map<Integer, List<ShopPromoHis>> promoBySoleMap =
                shopPromoHiss.stream().collect(Collectors.groupingBy(ShopPromoHis::getIsSole, Collectors.toList()));

        final BigDecimal[] TEMPORARY_STORAGE = {BigDecimal.ZERO};
        // isSole 0不可叠加 1可叠加
        promoBySoleMap.keySet().forEach(isSole -> {
            TEMPORARY_STORAGE[0] = BigDecimal.ZERO;
            // 按照目标数值(target)排倒序
            Stream<ShopPromoHis> sorted = promoBySoleMap.get(isSole).stream()
                    .sorted(Comparator.comparing(ShopPromoBase::getTarget).reversed());
            List<ShopPromoHis> collect = sorted.filter(shopPromoHis -> {
                // 根据优惠模式进行筛选
                switch (shopPromoHis.getModel()) {
                    case "enough": // 满减
                        final BigDecimal TARGET = shopPromoHis.getTarget();
                        // 含义：(isSole == 不可叠加) and (总花费 >= 目标金额) and (目标金额 > 记录的最大目标金额);
                        boolean b = (isSole == 0) && (totalCost.compareTo(TARGET) > -1) && (TARGET.compareTo(TEMPORARY_STORAGE[0]) > 0);
                        if (b) TEMPORARY_STORAGE[0] = TARGET;
                        return b;
                    case "immed": // 立减
                        return true;
                    case "random": // 随机
                        shopPromoHis.setDiscount(new BigDecimal(new Random().nextInt(shopPromoHis.getDiscount().intValue()) + 1));
                        return true;
                }
                return true;
            }).filter(shopPromoHis -> {
                // 根据客户身份进行筛选
                switch (shopPromoHis.getCustomer()) {
                    case "allCustomer": // 全部客户
                        // shopPromoHis.setDiscount(new BigDecimal(new Random().nextInt(shopPromoHis.getDiscount().intValue()) + 1));
                        return true;
                    case "newCustomer": // 新客户
                        return this.isNewCustomer(orderForOneVo.getShopId(), orderForOneVo.getMemberId());
                    case "oldCustomer": // 老客户
                        return !this.isNewCustomer(orderForOneVo.getShopId(), orderForOneVo.getMemberId());
                }
                return true;
            }).collect(Collectors.toList());
            promoBySoleMap.put(isSole, collect);
        });
        return promoBySoleMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
    }

    @Override
    public List<OrderStatusInfo> getOrderStatusInfo(String orderId) {
        return orderStatusInfoService.list(new QueryWrapper<OrderStatusInfo>().eq("order_id", orderId));
    }

    /**
     * 是否为新顾客
     *
     * @param shopId   店铺id
     * @param memberId 会员id
     * @return true/false
     */
    private boolean isNewCustomer(String shopId, String memberId) {
        return super.baseMapper.selectCount(new LambdaQueryWrapper<OrderBase>()
                .in(OrderBase::getStatus, 0, 1, 2, 3) // 只查有订单的
                .eq(OrderBase::getShopId, shopId)
                .eq(OrderBase::getMemberId, memberId)) == 0;
    }


    /**
     * 根据订单号打印
     *
     * @param orderNo 订单号
     */
    public void print(String orderNo) {
        log.info("根据订单号打印 in ->" + orderNo);
        OrderBase orderBase = this.selectOrderInfoByOrderNo(orderNo);
        // 获取店铺今天订单数
        int todayShopOrderNumber = super.baseMapper.selectCount(new LambdaQueryWrapper<OrderBase>()
                .eq(OrderBase::getShopId, orderBase.getShopId())
                .in(OrderBase::getStatus, -3, -2, 1, 2, 3)
                .apply("date_format(create_time, '%Y%m%d') = '" + DateUtils.yyyyMMdd.get().format(new Date()) + "'")
        );
        ShopBasic shopBasic = this.shopBasicService.getById(orderBase.getShopId());
        // 根据门店id获取打印机列表
        this.shopPrinterService.getShopPrinterByShopId(orderBase.getShopId()).forEach(shopPrinter -> {
            switch (shopPrinter.getType()) {
                case 1: // 飞鹅
                    FePrinterUtil.print(PrintUtil.getFePrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
                case 2: // 易联云
                    YlyPrinterUtil.print(PrintUtil.getYlyPrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
                case 3: // 芯烨云
                    XyyPrinterUtil.print(PrintUtil.getXyyPrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
            }
        });
    }

    public String getVerifyCode(String shopId) {
        boolean flag = true;
        String code = "";
        while (flag) {
            code = RandomUtil.randomNumbers(6);
            OrderBase orderBase = super.baseMapper.selectOne(new QueryWrapper<OrderBase>()
                    .eq("shop_id", shopId)
                    .eq("verify_code", code)
                    .last(" limit 1 "));
            if (null == orderBase) {
                flag = false;
            }
        }
        return code;
    }

}
